package com.demo.excel;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支持获取的数据类型
 *  原始数据类型，String ，Date ，<br>
 *  通过反射获取Model的类型
 *
 *
 * @author qingqing.liang
 * @create 2017-12-26
 **/
public class ExcelUtil {
    private static String title = "title";
    //
    private static String sufix = "xls";
    private static String fileName = "默认文件名";

    //列表头
    //单元格样式



    public static void main(String[] args) throws Exception {
        export();
    }
    public static OutputStream export() throws IOException {

        String[] titleArr = {"",""};
        List<String> dataList = new ArrayList<>();
        Workbook wb = null;
        //wb = export(fileName,titleArr,dataList);
        // Write the output to a file
        String file = "businessplan.xls";
        if(wb instanceof XSSFWorkbook) {
            file += "x";
        }
        FileOutputStream out = new FileOutputStream(file);
        wb.write(out);
        out.close();
        wb.close();

        return null;
    }


    /**
     * 设置标题单元格样式
     * @param wb
     * @return
     */
    private static CellStyle createHeaderStyle(Workbook wb){

        CellStyle style = wb.createCellStyle();
        Font monthFont = wb.createFont();
        monthFont.setFontHeightInPoints((short)11);
        monthFont.setColor(IndexedColors.WHITE.getIndex());
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setFont(monthFont);
        style.setWrapText(true);

        //设置边框

        //设置字体

        return style;
    }

    /**
     * 创建基础单元格的样式
     * @param wb  WorkBook ，HSSF和XSSF创建的CellStyle不同，需要传入wb。
     * @return
     */
    private static CellStyle createBorderedStyle(Workbook wb){
        BorderStyle thin = BorderStyle.THIN;
        short black = IndexedColors.BLACK.getIndex();

        CellStyle style = wb.createCellStyle();
        style.setBorderRight(thin);
        style.setRightBorderColor(black);
        style.setBorderBottom(thin);
        style.setBottomBorderColor(black);
        style.setBorderLeft(thin);
        style.setLeftBorderColor(black);
        style.setBorderTop(thin);
        style.setTopBorderColor(black);
        return style;
    }

    /**
     * TODO list泛型接收的数据类型
     * 导出只包含一个sheet的excel
     * @param excelConfig excel导出配置，如果没有配置全部使用默认配置
     * @param sheetName sheet名称
     * @param titleArr 标题数组
     * @param dataList 数据
     * @param fieldNameArr dataList中对象属性名数组，根据属性名数组决定导出字段顺序。
     * @return
     */
    public static  Workbook  export(ExcelConfig excelConfig,String sheetName, String[] titleArr, List dataList,String[] fieldNameArr) throws NoSuchFieldException, IllegalAccessException {

        Workbook wb;
        if(sufix.equals(excelConfig.getSuffix())) {
            wb = new HSSFWorkbook();
        }else{
            wb = new XSSFWorkbook();
        }

        Sheet sheet = wb.createSheet(sheetName);
        Row row;
        Cell cell;

        //设置表头
        CellStyle style = createHeaderStyle(wb);
        row = sheet.createRow(0);
        for(int i=0;i<titleArr.length;i++){
            cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(titleArr[i]);
        }

        //设置数据
        Field field;
        CellStyle cellStyle = createBorderedStyle(wb);
        int rownum = 1;
        boolean flag = true;
        //对象属性的类型
        Map<String,Field> fieldMap = new HashMap<>();
        for (Object obj: dataList) {
            //获取对象信息
            if(flag){
                Class clazz  = obj.getClass();
                for(String fieldName:fieldNameArr){
                    field  = clazz.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    fieldMap.put(fieldName,field);
                }
                flag = false;
            }

            row = sheet.createRow(rownum);
            for(int j=0;j<fieldNameArr.length;j++){
                cell = row.createCell(j);
                cell.setCellStyle(cellStyle);
                String fieldName = fieldNameArr[j];
                field =  fieldMap.get(fieldName);
                String simpleName = field.getType().getSimpleName();
                //    根据不同的数据类型调用不同设置方法
                setValue(cell,simpleName,field.get(obj));

            }
            rownum++;
        }
        return wb;
    }

    /**
     * 设置cell值.
     * 根据不同的数据类型，调用poi不同方法
     * @param cell
     * @param simpleName 数据类型的简称
     * @param value
     */
    private static void setValue(Cell cell,String simpleName,Object value){
        if(value == null){
            return ;
        }
        switch (simpleName){
            case DataType.BOOLEAN:
                cell.setCellValue((boolean)value);
                break;
            case DataType.CHAR:
                cell.setCellValue((char)value);
                break;
            case DataType.INTEGER:
                cell.setCellValue((int)value);
                break;
            case DataType.LONG:
                cell.setCellValue((long)value);
                break;
            case DataType.FLOAT:
                cell.setCellValue((float)value);
                break;
            case DataType.DOUBLE:
                cell.setCellValue((double)value);
                break;
            case DataType.STRING:
                cell.setCellValue((String)value);
                break;

            default:

        }
    }


    private static class DataType{
       static final String CHAR = "Char";
       static final String BOOLEAN = "Boolean";
       static final String INTEGER = "Integer";
       static final String LONG = "Long";
       static final String FLOAT = "Float";
       static final String DOUBLE = "Double";
       static final String STRING = "String";
        ;
    }




}
